package com.coszero.utilslibrary.utils;


import android.annotation.SuppressLint;
import android.content.Context;

import com.coszero.utilslibrary.R;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Random;

/**
 * @author xmqian
 * @date 2018/5/29
 * @desc 获取系统时间，和格式化时间格式
 * @version 1
 */
public class TimeUtils {
    private final static String TAG = "TimeUtils";
    private final static long minute = 60 * 1000;// 1分钟
    private final static long hour = 60 * minute;// 1小时
    private final static long day = 24 * hour;// 1天
    private final static long month = 31 * day;// 月
    private final static long year = 12 * month;// 年

    /*时间格式可根据需要进行更改*/
    /**
     * 日期格式：yyyy-MM-dd HH:mm:ss
     **/
    public static final String DF_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    /**
     * 日期格式：yyyy-MM-dd HH:mm
     **/
    public static final String DF_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";

    /**
     * 日期格式：yyyy-MM-dd
     **/
    public static final String DF_YYYY_MM_DD = "yyyy-MM-dd";

    /**
     * 日期格式：HH:mm:ss
     **/
    public static final String DF_HH_MM_SS = "HH:mm:ss";

    /**
     * 日期格式：HH:mm
     **/
    public static final String DF_HH_MM = "HH:mm";
    /**
     * 日期格式：MM-dd HH:mm
     **/
    public static final String DF_MM_DD_HH_MM = "MM-dd HH:mm";


    private static Calendar mCalendar;
    private static SimpleDateFormat format;
// <editor-fold desc="返回当前时间" defaultstate="collapsed">

    /**
     * 获取未经处理的时间格式
     *
     * @return 返回long类型的时间格式
     */
    public static long getLongTime() {
        return System.currentTimeMillis();
    }

    /**
     * 以默认格式获取当前的系统时间
     *
     * @return 返回月-日 时：分 格式的时间
     */
    public static String getCurrentTime() {
        return new SimpleDateFormat(DF_MM_DD_HH_MM, Locale.CHINA)
                .format(new Date());
    }

    /**
     * 获取系统当前日期
     *
     * @return date
     */
    public static Date getCurrentDate() {
        return new Date();
    }

    /**
     * 以你所需要的格式获取当前的系统时间
     *
     * @param rgx 传入你需要的时间格式
     * @return 返回你所需要格式的时间字符串
     */
    public static String getCurrentTime(String rgx) {
        return new SimpleDateFormat(rgx, Locale.CHINA)
                .format(new Date());
    }

    /**
     * 获取当前日期月
     *
     * @return 返回当前月份
     */
    public static int getMonth() {
        mCalendar = Calendar.getInstance();
        int mMonth = mCalendar.get(Calendar.MONTH) + 1;
        return mMonth;
    }

    /**
     * 获取当前日期日
     *
     * @return 返回当前月的日
     */
    public static int getDay() {
        mCalendar = Calendar.getInstance();
        int mDay = mCalendar.get(Calendar.DATE);
        return mDay;
    }

    /**
     * 获取当前日期年
     *
     * @return 返回当前年
     */
    public static int getYear() {
        mCalendar = Calendar.getInstance();
        int year = mCalendar.get(Calendar.YEAR);
        return year;
    }
//</editor-fold>

    // <editor-fold desc="时间操作" defaultstate="collapsed">
// <editor-fold desc="判断" defaultstate="collapsed">

    /**
     * 验证日期是否比当前日期早
     *
     * @param startTime 当前系统时间
     * @param finishTime 需要比较的时间
     * @return 返回当前时间是否比finishTime早，早：true;晚false
     */
    public static boolean compareData(String startTime, String finishTime) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DF_YYYY_MM_DD_HH_MM_SS);
        boolean isLast = false;
        try {
            Date startDate = dateFormat.parse(startTime);
            Date finishDate = dateFormat.parse(finishTime);
            isLast = startDate.before(finishDate);
        } catch (ParseException e) {
            System.out.println("比较失败，原因：" + e.getMessage());
        }
        return isLast;
    }

    /**
     * 判断两日期是否同一天
     *
     * @param str1 2019-01-30
     * @param str2 2019-01-29
     * @return
     */
    @SuppressLint("SimpleDateFormat")
    public static boolean isToday(String str1, String str2) {
        Date day1 = null, day2 = null;
        day1 = parseDate(str1);
        day2 = parseDate(str2);
        SimpleDateFormat sdf = new SimpleDateFormat(DF_YYYY_MM_DD);
        String ds1 = sdf.format(day1);
        String ds2 = sdf.format(day2);
        return ds1.equals(ds2);
    }
//</editor-fold>
    // <editor-fold desc="转化" defaultstate="collapsed">

    /**
     * 传入时间 算出星期几
     *
     * @param str 2014-1-3
     * @param days 1:2014-1-4 类推
     * @return 返回字符资源
     */
    @SuppressLint("SimpleDateFormat")
    public static int getWeekName(String str, int days) {
        int dateStr = R.string.ut_monday;
        try {
            DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
            Date date = df.parse(str);
            SimpleDateFormat dateFormat = new SimpleDateFormat(DF_YYYY_MM_DD);
            Calendar c = Calendar.getInstance();
            Date d = dateFormat.parse(dateFormat.format(date));
            c.setTime(d);
            c.add(Calendar.DAY_OF_MONTH, days);
            switch (c.get(Calendar.DAY_OF_WEEK) - 1) {
                case 0://周日
                    dateStr = R.string.ut_sunday;
                    break;
                case 1://周一
                    dateStr = R.string.ut_monday;
                    break;
                case 2://周二
                    dateStr = R.string.ut_thursday;
                    break;
                case 3://周三
                    dateStr = R.string.ut_wednesday;
                    break;
                case 4://周四
                    dateStr = R.string.ut_thursday;
                    break;
                case 5://周五
                    dateStr = R.string.ut_friday;
                    break;
                case 6://周六
                    dateStr = R.string.ut_saturday;
                    break;
                default:
                    dateStr = R.string.ut_monday;
                    LogX.e(TAG, "### getWeekName：星期数值错误");
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dateStr;
    }

    /**
     * 将日期字符串转成日期
     *
     * @param strDate 字符串日期，需要"-"分割
     * @return java.util.date日期类型
     */
    @SuppressLint("SimpleDateFormat")
    public static Date parseDate(String strDate) {
        return parseDate(strDate, "-");
    }

    @SuppressLint("SimpleDateFormat")
    public static Date parseDate(String strDate, String split) {
        if (!strDate.contains(split)) {
            LogX.e(TAG, "parseDate：" + "分隔符不正确");
            return null;
        }
        DateFormat dateFormat = new SimpleDateFormat("yyyy" + split + "MM" + split + "dd" + " HH:mm:ss");
        Date returnDate = null;
        try {
            returnDate = dateFormat.parse(strDate);
        } catch (ParseException e) {
            LogX.e(TAG, "### parseDate:" + "日期格式错误" + strDate);
        }
        return returnDate;
    }

    /**
     * 传入一个String转化为long
     *
     * @param param 传入的时间,格式为"-"
     * @return 返回一个long型
     * @throws ParseException
     */
    @SuppressLint("SimpleDateFormat")
    public static Long stringParserLong(String param) {
        return parseDate(param).getTime();
    }

    /**
     * 将long类型日期以yyyy-MM-dd HH:mm:ss格式化
     *
     * @param dateL 传入以Date获取的long类型值
     * @return 返回已默认格式转化的时间字符串
     */
    @SuppressLint("SimpleDateFormat")
    public static String formatDateTime(long dateL) {
        return formatDateTime(dateL, DF_YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 格式化Date类型的日期
     *
     * @param date date 如果是改造的，格式要和获取的格式一致
     * @param rgx 需要获取的格式
     * @return 从日历类中获取年/月/日
     * @deprecated Use @link {{@link #formatDateTime(Date, String)}}
     */
    public static String getFormatDate(Date date, String rgx) {
        return formatDateTime(date.getTime(), rgx);
    }

    /**
     * 格式化Date类型的日期
     *
     * @param date date 如果是改造的，格式要和获取的格式一致
     * @param rgx 需要获取的格式
     * @return 从日历类中获取年/月/日
     */
    public static String formatDateTime(Date date, String rgx) {
        return formatDateTime(date.getTime(), rgx);
    }

    /**
     * 将long类型日期格式化为你想要的格式
     *
     * @param dateL 传入以Date获取的long类型值
     * @param rgx 传入你想转化的格式 yyyy-MM-dd HH:mm:ss
     * @return 返回已默认格式转化的时间字符串
     */
    @SuppressLint("SimpleDateFormat")
    public static String formatDateTime(long dateL, String rgx) {
        SimpleDateFormat sdf = new SimpleDateFormat(rgx);
        Date date = new Date(dateL);
        return sdf.format(date);
    }
    //</editor-fold>


    /**
     * 获取日期格式 年/月/日
     *
     * @param mCalendar calendar是带本地时区的
     * @param splitChar 分隔符
     * @return 从日历类中获取年/月/日
     */
    private static String getYMD(Calendar mCalendar, String splitChar) {
        int mYear = mCalendar.get(Calendar.YEAR);
        int mMonth = mCalendar.get(Calendar.MONTH) + 1;
        int mDay = mCalendar.get(Calendar.DATE);
        return mYear + splitChar + mMonth + splitChar + mDay;
    }

    /**
     * 获取时间格式 时：分
     *
     * @param mCalendar calendar是带本地时区的
     * @return 从日历类中获取当前时间时：分
     * @deprecated Use @link{{@link #getHM(Calendar)}}
     */
    public static String getTime(Calendar mCalendar) {
        int mHour = mCalendar.get(Calendar.HOUR_OF_DAY);
        int mMinute = mCalendar.get(Calendar.MINUTE);
        return mHour + ":" + mMinute;
    }

    /**
     * 获取时间格式 时：分
     *
     * @param mCalendar calendar是带本地时区的
     * @return 从日历类中获取当前时间时：分
     */
    public static String getHM(Calendar mCalendar) {
        int mHour = mCalendar.get(Calendar.HOUR_OF_DAY);
        int mMinute = mCalendar.get(Calendar.MINUTE);
        return mHour + ":" + mMinute;
    }

    /**
     * 对日期进行增加操作
     *
     * @param target 需要进行运算的日期
     * @param hour 小时
     * @return 返回增加后的date
     */
    public static Date addDateTime(Date target, double hour) {
        if (null == target || hour < 0) {
            return target;
        }

        return new Date(target.getTime() + (long) (hour * 60 * 60 * 1000));
    }

    /**
     * 对日期进行相减操作
     *
     * @param target 需要进行运算的日期
     * @param hour 小时
     * @return 返回减去的date
     */
    public static Date subDateTime(Date target, double hour) {
        if (null == target || hour < 0) {
            return target;
        }
        return new Date(target.getTime() - (long) (hour * 60 * 60 * 1000));
    }


    /**
     * 转换年月日的分隔符“-”、“/”
     * 如果日期带时分秒,则会返回时分秒的格式
     *
     * @param changeTime 需要转换的日期
     * @return 返回转换分隔符后的日期 “-”转“/”或者“/”转“-”
     */
    public static String changeSplitCharYMD(String changeTime) {
        try {
            String formatStr;
            String changeSplitChar;
            if (changeTime.contains("-")) {
                formatStr = "yyyy-MM-dd";
                changeSplitChar = "/";
            } else if (changeTime.contains("/")) {
                formatStr = "yyyy/MM/dd";
                changeSplitChar = "-";
            } else {
                LogX.e(TAG, "changeSplitCharYMD: 日期分隔符不是“-”或“/”");
                return changeTime;
            }
            SimpleDateFormat format = new SimpleDateFormat(formatStr);
            Date date = format.parse(changeTime);
            return formatDateTime(date, "yyyy" + changeSplitChar + "MM" + changeSplitChar + "dd");
        } catch (ParseException e) {
            return changeTime;
        }
    }


    /**
     * 用当前时间给图片命名
     *
     * @return 返回yyyyMMdd_HHmmss格式的字符串
     */
    public static String getFileName() {
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
        Random random = new Random();
        int num = random.nextInt() * 100;
        return dateFormat.format(date) + num;
    }

    /**
     * 以友好的方式显示时间
     *
     * @param diffTime 传入的时间
     * @return 几分钟前，几小时前的那种朋友圈时间格式
     */
    public static String formatFriendlyTime(Context context, Long diffTime) {
        if (diffTime < 0) {
            return "Unknown";
        }
        long diff = diffTime;
        long r = 0;

        if (diff > year) {
            r = (diff / year);
            //年
            return r + ResourceUtils.getString(context, R.string.ut_year_ago);
        }
        if (diff > month) {
            r = (diff / month);
            //月
            return r + ResourceUtils.getString(context, R.string.ut_month_ago);
        }
        if (diff > day) {
            r = (diff / day);
            if (r == 1) {
                //昨天
                return ResourceUtils.getString(context, R.string.ut_yesterday);
            }
            if (r == 2) {
                //前天
                return ResourceUtils.getString(context, R.string.ut_before_yesterday);
            }
            //n天前
            return r + ResourceUtils.getString(context, R.string.ut_day_ago);
        }
        if (diff > hour) {
            r = (diff / hour);
            //n小时前
            return r + ResourceUtils.getString(context, R.string.ut_hour_ago);
        }
        if (diff > minute) {
            r = (diff / minute);
            //n分钟前
            return r + ResourceUtils.getString(context, R.string.ut_minute_ago);
        }
        //刚刚
        return ResourceUtils.getString(context, R.string.ut_now);
    }

    /**
     * 返回时间差
     *
     * @param nowtime 开始时间
     * @param endtime 结束时间
     * @return 返回时间差，毫秒数
     */
    public static long difference(String nowtime, String endtime) {
        String split = "-";
        if (nowtime.contains("-") && endtime.contains("-")) {
            split = "-";
        } else if (nowtime.contains("/") && endtime.contains("/")) {
            split = "/";
        } else {
            LogX.e(TAG, "### timeDifference:" + "分隔符不正确");
            return 0;
        }
        long diff;
        //系统时间转化为Date形式
        Date dstart = parseDate(nowtime, split);
        //活动结束时间转化为Date形式
        Date dend = parseDate(endtime, split);
        //算出时间差，用ms表示
        diff = dend.getTime() - dstart.getTime();
        //返回时间差
        return diff;
    }

    /**
     * 将毫秒时长格式化为 00:00:00 这种格式
     *
     * @param time 将毫秒格式化为时间
     * @return 返回格式化好的时间，最大单位为小时
     */
    public static String secToTime(long time) {
        String timeStr = null;
        int hour = 0;
        int minute = 0;
        int second = 0;
        if (time <= 0) {
            return "00:00";
        } else {
            time = time / 1000;
            minute = (int) (time / 60);
            if (minute < 60) {
                second = (int) (time % 60);
                timeStr = unitFormat(minute) + ":" + unitFormat(second);
            } else {
                hour = minute / 60;
                if (hour > 99) {
                    return "99:59:59";
                }
                minute = minute % 60;
                second = (int) (time - hour * 3600 - minute * 60);
                timeStr = unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second);
            }
        }
        return timeStr;
    }

    private static String unitFormat(int i) {
        String retStr = null;
        if (i >= 0 && i < 10) {
            retStr = "0" + i;
        } else {
            retStr = "" + i;
        }
        return retStr;
    }
}
